/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// TGUI - Texus's Graphical User Interface
// Copyright (C) 2012 Bruno Van de Velde (VDV_B@hotmail.com)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
//    you must not claim that you wrote the original software.
//    If you use this software in a product, an acknowledgment
//    in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
//    and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


#ifndef _TGUI_CHECKBOX_INCLUDED_
#define _TGUI_CHECKBOX_INCLUDED_

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace tgui
{
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    struct TGUI_API Checkbox : public OBJECT
    {
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Default constructor
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        Checkbox();


        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Copy constructor
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        Checkbox(const Checkbox& copy);


        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Destructor
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        virtual ~Checkbox();


        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Overload of assignment operator
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        Checkbox& operator= (const Checkbox& right);


        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        /// The path should point to a folder with the needed images.
        /// The folder must contain an info.txt file that will give more information about the checkbox.
        /// Apart from the optional images you will always need a checked and an unchecked image.
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        bool load(const std::string pathname);


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Changes the size of the checkbox. Note that this function will undo all scaling, as it just
        /// calculates the correct scale factors for you. It is an alternative to setScale.
        /// Note that the checkbox has to be loaded correctly before calling this function.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        void setSize(float width, float height);


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Returns the size of the checkbox, unaffected by scaling.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        Vector2u getSize() const;


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Returns the size of the checkbox, after the scaling transformation.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        Vector2f getScaledSize() const;


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Returns the pathname that was used to load the checkbox.
        /// When the checkbox has not been loaded yet then this function will return an empty string.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        std::string getLoadedPathname();


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Checks the checkbox.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        virtual void check();


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Unchecks the checkbox.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        virtual void uncheck();


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Returns whether the checkbox is checked or not.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        bool isChecked();


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Changes the text of the checkbox.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        void setText(const std::string text);


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Returns the text of the checkbox.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        std::string getText();


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Changes the font of the text. When you don't call this function then the global font will be use.
        /// This global font can be changed by calling the setGlobalFont function from Panel.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        void setTextFont(const sf::Font& font);


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Returns the font of the text.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        const sf::Font& getTextFont();


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Changes the color of the text.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        void setTextColor(const sf::Color& color);


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Returns the color of the text.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        const sf::Color& getTextColor();


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Changes the character size of the text.
        /// When the size is 0 then te text is automatically scaled to be as big as the image (default).
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        void setTextSize(const unsigned int size);


        //////////////////////////////////////////////////////////////////////////////////////////////////////
        /// Returns the character size of the text.
        /// It is possible that this function returns 0, which means that the text is auto-scaled.
        //////////////////////////////////////////////////////////////////////////////////////////////////////
        unsigned int getTextSize();


        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // These functions are used to receive callback from EventManager.
        // You normally don't need them, but you can use them to simulate an event.
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        bool mouseOnObject(float x, float y);
        void leftMousePressed(float x, float y);
        void leftMouseReleased(float x, float y);
        void mouseMoved(float x, float y);
        void keyPressed(sf::Keyboard::Key key);
        void objectFocused();


        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private:

        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Because this struct is derived from sf::Drawable, you can just call the draw function from your sf::RenderTarget.
        // This function will be called and it will draw the checkbox on the render target.
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        void draw(sf::RenderTarget& target, sf::RenderStates states) const;


        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public:

        /// When this boolean is true (default) then the checkbox will also be checked/unchecked by clicking on the text.
        bool allowTextClick;

        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    protected:

        // This is the checked flag. When the checkbox is checked then this variable will be true.
        bool m_Checked;


        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    private:

        // This will contain the text that is written next to checkbox.
        sf::Text m_Text;

        // This will store the size of the text ( 0 to auto size )
        unsigned int m_TextSize;

        // The SFML textures
        sf::Texture* m_TextureUnchecked;
        sf::Texture* m_TextureChecked;
        sf::Texture* m_TextureMouseHover;
        sf::Texture* m_TextureFocused;

        // The SFML sprites
        sf::Sprite  m_SpriteUnchecked;
        sf::Sprite  m_SpriteChecked;
        sf::Sprite  m_SpriteMouseHover;
        sf::Sprite  m_SpriteFocused;

        // The pathname used to load the checkbox
        std::string m_LoadedPathname;


        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    };

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#endif //_TGUI_CHECKBOX_INCLUDED_
